import Vue from 'vue'
import App from './App.vue'
import router from './router'   //应用会先配置好路由的规则
import store from './store'
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
import "reset-css"
// import VXETable from 'vxe-table'
// import 'vxe-table/lib/style.css'

import "./styles/global.css"
import MyPlugin from './plugins/myPlugins'
import DaxiaUI from './plugins/daxiaUI'

// import _ from 'lodash' //导入_对象
// Vue.prototype._ = _
import uniq  from 'lodash/uniq'
Vue.prototype.$uniq = uniq

// ========================================================= 全局属性：=============================================================
// ========================================================= 全局属性：=============================================================
// ========================================================= 全局属性：=============================================================

// console.log(Vue.name, Vue.length, Vue.version, Vue.options, Vue.util);

Vue.config.productionTip = false          //设置为 `false` 以阻止 vue 在启动时生成生产提示。

// performance：设置为true启用浏览器开发工具的性能/时间线面板中对组件初始化、编译、渲染和打补丁的性能追踪。
// Vue.config.performance = true

Vue.config.silent = false       //是否取消 Vue 所有的日志与警告。(默认false)

Vue.config.devtools = true      //配置是否允许 vue-devtools 检查代码。开发版本默认为 `true`，生产版本默认为 `false`。  

// Vue.config.keyCodes  //给 `v-on` 自定义键位别名。

// Vue.config.optionMergeStrategies.forMixin = ()=>{}         //自定义合并策略的选项。

/** ignoredElements
 * 须使 Vue 忽略在 Vue 之外的自定义元素 (e.g. 使用了 Web Components APIs)。
 * 否则，它会假设你忘记注册全局组件或者拼错了组件名称，从而抛出一个关于 `Unknown custom element` 的警告。
 */
// Vue.config.ignoredElements

// Vue.config.errorHandler = (err, vm, info)=>{}        //设置组件的渲染和观察期间未捕获错误的处理函数，可获取错误信息和 Vue 实例。

// Vue.config.warnHandler = ()=>{}        //为 Vue 的运行时的警告赋予一个自定义处理函数。

// ========================================================= 全局方法：=============================================================
// ========================================================= 全局方法：=============================================================
// ========================================================= 全局方法：=============================================================

// Vue.use(plugin，[ options ])   plugin：所要安装的插件    options：（可选），表示要传给插件的一些东西
/** 安装 Vue.js 插件
 * 如果插件是一个对象，这个对象必须提供`install`方法。如果插件是一个函数，它会被作为 install 方法。
 * 插件中的 install 方法调用时，会将 Vue 作为插件中的`install`函数的第一个参数传入。
 * 注意点：
 *    1. 该方法需要在调用 `new Vue()` 之前被调用。
 *    2. 当 install 方法被同一个插件多次调用，插件将只会被安装一次。
 *    3. 
 */
Vue.use(ElementUI)
// Vue.use(VXETable)
Vue.use(MyPlugin)
Vue.use(DaxiaUI)
// ————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————

// Vue.nextTick()
/** 所有的 DOM 发生更新就会调用这个方法的回调函数
 * 在下次 DOM 更新循环结束之后执行它延迟回调。在修改数据之后立即使用这个方法，获取更新后的 DOM。
 */

// ————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————

// Vue.set(target，propertyName/index，value )
/**
 * 向响应式对象中添加一个 property，并确保这个新 property 同样是响应式的，且触发视图更新。
 */

// ————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————

// Vue.delete( target, propertyName/index )
/**
 * 删除对象的 property。如果对象是响应式的，确保删除能触发更新视图。
 */

// ————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————

// Vue.component():
/**注册一个全局的组件 。之后在某个组件中要使用这个组件就可以不用引入直接使用
 * 必须 Vue 实例创建之前注册全局组件
*/
// Vue.component("MyComponent", "组件的文件路径"/"组件的实例（就是先把组件引入这个文件，这里再写它的别名）")
Vue.component("MyComponent", {})        //如果是使用PascalCase (首字母大写命名）的方式，那么引用的时候两种方式都可以
Vue.component("My-component", {})       //如果使用短横线分隔命名的方式注册，那么在引用组件的时候也必须是这个方式

// ————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————

// Vue.directive
/**注册一个全局的自定义指令
 * 参数：第一个参数是指令的名称，第二个参数是指令的处理逻辑方法（钩子函数对象）
 */
// const has = Vue.directive("has",{    //方案一
//   inserted(el,binding,vnode){
//     const val = binding.value;
//     console.log(val);
//     if(!store.state.buttonPermission[val]){
//       el.style.display = "none"
//     }
//   }
// })
const has2 = Vue.directive("has2", {    //方案二：这种方案更普遍使用
  inserted(el,binding,vnode){
    const val = binding.value;
    // console.log(val);
    if(!store.state.buttonPermission2.includes(val)){
      el.style.display = "none"
    }
  }
})

// ————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————

// Vue.filter()
/**声明全局的过滤器。vue3中移除了该方法。
 * 参数：第一个参数是过滤器名称，
 *      第二个参数是处理逻辑函数：
 *          要过滤改造的数据        传递过滤要用的值
*/
Vue.filter("two", (val, first, second)=>{
  if(typeof(val)==="number"){
    return val.toFixed(2) + first + second;
  }
})

// ————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————

// Vue.mixin()
/** 全局混入
 * 可以影响到每一个组件实例中的数据和选项方法，需要谨慎使用
 * 组件和mixin的数据相同会被合并，并且以组件的为主
 * 组件和mixin中的 computed metheds filter directives 等对象选项的键名相同会被合并，以组件的为主
 * 组件和mixin的钩子函数相同时，两者的都会执行，并且mixin的钩子函数会在组件的之前被执行
*/
Vue.mixin({
  // 这里面的内容类似于vue实例的构建选项
})

// ————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————

// Vue.extend()
/** 使用基础 Vue 构造器，创建出一个“子类”。参数是一个包含组件构建选项的对象。 */

// ————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————

// Vue.observable()
/** 让一个对象可响应。Vue 内部会用它来处理 `data` 函数返回的对象。 */

// ————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————

// Vue.compile()
/**
 * 将一个模板字符串编译成 render 函数。只在完整版时可用。
 */
// ————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————

new Vue({
  router,
  store,
  render: h => h(App)
}).$mount('#app')
